package com.block.common.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.ICountCommonService;
import com.block.common.service.LogFactory;
import com.block.db.entity.ChannelInfo;
import com.block.db.entity.CountInfo;
import com.block.db.mapper.CountInfoMapper;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;

@Service
public class CountInfoCommonServiceImpl implements ICountCommonService {

    private static Logger log = LogFactory.getCommLog();

    @Resource
    CountInfoMapper countInfoMapper;
    @Autowired
    IChannelCommonService channelCommonService;
    @Autowired
    NotifyExceptionService notifyExceptionService;

    @Async
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
    public void calculateDataInfo2(CountInfoDTO countInfoDTO) {

        try {


            log.info("【保存统计结果】【countInfoDTO】{}", JSON.toJSONString(countInfoDTO));
            ChannelInfo channelInfo = channelCommonService.getChannelInfoCache(countInfoDTO.getChannelCode());
            if (ObjectUtil.isEmpty(channelInfo)) {
                log.error("【保存统计结果】渠道信息为空【channelCode】{}", countInfoDTO.getChannelCode());
                return;
            }

            CountInfo countInfo = countInfoMapper.getEntryByCodeAndDateLock(countInfoDTO.getDateInfo(), countInfoDTO.getChannelCode());
            if (ObjectUtil.isEmpty(countInfo)) {
                log.info("【保存统计结果】统计信息为空【dateinfo】{}【channelCode】{}", countInfoDTO.getDateInfo(), countInfoDTO.getChannelCode());
                countInfo = new CountInfo();
                countInfo.setDateInfo(countInfoDTO.getDateInfo());
                countInfo.setChannelCode(countInfoDTO.getChannelCode());
                countInfo.setChannelName(channelInfo.getChannelName());
                countInfo.setChannelType(channelInfo.getChannelType());
                countInfo.setChannelRate(channelInfo.getChannelRate());
                countInfo.setChannelPrice(channelInfo.getChargeAmount());
                boolean save = countInfoMapper.insert(countInfo) > 0;
                log.info("【保存统计结果】新增【save】{}【dateInfo】{}【channelCode】{}", save, countInfoDTO.getDateInfo(), countInfoDTO.getChannelCode());
                if (!save) {
                    notifyExceptionService.notifyNoticeInfo("COUNT", "UV统计", "新增失败："+JSON.toJSONString(countInfoDTO), null);
                    return;
                }
            }

            countInfo = countInfoMapper.getByIdLock(countInfo.getId());
            CountInfo updateEntry = this.handleCountData(countInfo, countInfoDTO);
            boolean updateRes = countInfoMapper.updateById(updateEntry) > 0;
            log.info("【保存统计结果】更新【updateRes】{}【updateEntry】{}", updateRes, JSON.toJSONString(updateEntry));
            if (!updateRes) {
                notifyExceptionService.notifyNoticeInfo("COUNT", "UV统计", "更新失败："+JSON.toJSONString(countInfoDTO), null);
                return;
            }
        } catch (Exception exception) {
            log.error("【保存统计结果】统计出现异常【countInfo】"+JSON.toJSONString(countInfoDTO), exception);
            notifyExceptionService.notifyNoticeInfo("COUNT", "UV统计", "统计异常："+JSON.toJSONString(countInfoDTO), exception);
        }
    }

    /**
     * 统计产品列表的访问次数
     */
    @Async
    @Override
    public void countProdListUvNumber(String channelCode, String reqIp) {
        String dateInfo = LocalDate.now().toString();

        CountInfoDTO countInfoDTO = new CountInfoDTO();
        countInfoDTO.setUvProdList(1);
        countInfoDTO.setChannelCode(channelCode);
        countInfoDTO.setDateInfo(dateInfo);
        this.calculateDataInfo2(countInfoDTO);
    }


    public CountInfo handleCountData(CountInfo countInfo, CountInfoDTO countInfoDTO) {

        CountInfo updateEntry = new CountInfo();
        updateEntry.setId(countInfo.getId());

        if (ObjectUtil.isNotEmpty(countInfoDTO.getUvCount())) {
            updateEntry.setUvCount(countInfo.getUvCount() + countInfoDTO.getUvCount());
            updateEntry.setUvCost(countInfo.getUvCost().add(countInfoDTO.getUvCost()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRegisterCount())) {
            updateEntry.setRegisterCount(countInfo.getRegisterCount() + countInfoDTO.getRegisterCount());
            updateEntry.setRegisterCost(countInfo.getRegisterCost().add(countInfoDTO.getRegisterCost()));
            updateEntry.setRegisterCountReal(countInfo.getRegisterCountReal() + countInfoDTO.getRegisterCountReal());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getLoginCount())) {
            updateEntry.setLoginCount(countInfo.getLoginCount() + countInfoDTO.getLoginCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getAuthGoodCount())) {
            updateEntry.setAuthGoodCount(countInfo.getAuthGoodCount() + countInfoDTO.getAuthGoodCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getAuthCount())) {
            updateEntry.setAuthCount(countInfo.getAuthCount() + countInfoDTO.getAuthCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getDownloadCount())) {
            updateEntry.setDownloadCount(countInfo.getDownloadCount() + countInfoDTO.getDownloadCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getProUvCount())) {
            updateEntry.setProUvCount(countInfo.getProUvCount() + countInfoDTO.getProUvCount());
            updateEntry.setProUvProfit(countInfo.getProUvProfit().add(countInfoDTO.getProUvProfit()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getProUnionCount())) {
            updateEntry.setProUnionCount(countInfo.getProUnionCount() + countInfoDTO.getProUnionCount());
            updateEntry.setProUnionProfit(countInfo.getProUnionProfit().add(countInfoDTO.getProUnionProfit()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getUvProdList())) {
            updateEntry.setUvProdList(countInfo.getUvProdList() + countInfoDTO.getUvProdList());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRequestWechatCount())) {
            updateEntry.setRequestWechatCount(countInfo.getRequestWechatCount() + countInfoDTO.getRequestWechatCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRequestQqCount())) {
            updateEntry.setRequestQqCount(countInfo.getRequestQqCount() + countInfoDTO.getRequestQqCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRiskRequestNumber())) {
            updateEntry.setRiskRequestNumber(countInfo.getRiskRequestNumber() + countInfoDTO.getRiskRequestNumber());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getRiskSuccessNumber())) {
            updateEntry.setRiskSuccessNumber(countInfo.getRiskSuccessNumber() + countInfoDTO.getRiskSuccessNumber());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getSpePushCount())) {
            updateEntry.setSpePushCount(countInfo.getSpePushCount() + countInfoDTO.getSpePushCount());
            updateEntry.setSpePushAmount(NumberUtil.add(countInfo.getSpePushAmount(), countInfoDTO.getSpePushAmount()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getFormPushCount())) {
            updateEntry.setFormPushCount(countInfo.getFormPushCount() + countInfoDTO.getFormPushCount());
            updateEntry.setFormPushAmount(NumberUtil.add(countInfo.getFormPushAmount(), countInfoDTO.getFormPushAmount()));
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getSourceCount())) {
            updateEntry.setSourceCount(countInfo.getSourceCount() + countInfoDTO.getSourceCount());
        }

        if (ObjectUtil.isNotEmpty(countInfoDTO.getSourceCost())) {
            updateEntry.setSourceCost(NumberUtil.add(countInfo.getSourceCost(), countInfoDTO.getSourceCost()));
        }

        return updateEntry;
    }

}
